home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D GFX
/
3D GFX.iso
/
amiutils
/
i_l
/
irit5
/
cagd_lib
/
cagdruld.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-30
|
7KB
|
175 lines
/******************************************************************************
* CagdRuld.c - Ruled srf operator out of given two profiles. *
*******************************************************************************
* Written by Gershon Elber, May. 91. *
******************************************************************************/
#include "cagd_loc.h"
/*****************************************************************************
* DESCRIPTION: M
* Constructs a ruled surface between the two provided curves. M
* OtherOrder and OtherLen (equal for Bezier) specifies the desired order and M
* refineness level (if Bspline) of the other ruled direction. M
* *
* PARAMETERS: M
* Crv1, Crv2: The two curves to form a ruled surface in between. M
* OtherOrder: Usually two, but one can specify higher orders in the ruled M
* direction. OtherOrder must never be larger than OrderLen. M
* OtherLen: Usually two control points in the ruled direction which M
* necesitates a linear interpolation. M
* *
* RETURN VALUE: M
* CagdSrfStruct *: The rule surface. M
* *
* KEYWORDS: M
* CagdRuledSrf, ruled surface, surface constructors M
*****************************************************************************/
CagdSrfStruct *CagdRuledSrf(CagdCrvStruct *Crv1,
CagdCrvStruct *Crv2,
int OtherOrder,
int OtherLen)
{
CagdSrfStruct *Srf;
int i, j, k, MaxCoord, Len;
CagdPointType PType;
CagdBType IsNotRational;
CagdRType **SrfPoints, *Crv1SrcPt, *Crv2SrcPt, *SrfDestPt, t, t1,
**Crv1Points, **Crv2Points;
Crv1 = CagdCrvCopy(Crv1);
Crv2 = CagdCrvCopy(Crv2);
CagdMakeCrvsCompatible(&Crv1, &Crv2, TRUE, TRUE);
MaxCoord = CAGD_NUM_OF_PT_COORD(Crv1 -> PType),
Len = Crv1 -> Length;
PType = Crv1 -> PType;
IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv1);
Crv1Points = Crv1 -> Points;
Crv2Points = Crv2 -> Points;
switch (Crv1 -> GType) {
case CAGD_CBEZIER_TYPE:
Srf = BzrSrfNew(Len, OtherLen, PType);
break;
case CAGD_CBSPLINE_TYPE:
Srf = BspPeriodicSrfNew(Len, OtherLen, Crv1 -> Order, OtherOrder,
Crv1 -> Periodic, FALSE, PType);
CAGD_GEN_COPY(Srf -> UKnotVector, Crv1 -> KnotVector,
sizeof(CagdRType) * (CAGD_CRV_PT_LST_LEN(Crv1) +
Crv1 -> Order));
BspKnotUniformOpen(OtherLen, OtherOrder, Srf -> VKnotVector);
break;
case CAGD_CPOWER_TYPE:
CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
return NULL;
default:
CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
return NULL;
}
/* Copy the control mesh - first row is exactly the same as the first */
/* curve while last row is the same as second curve. */
/* The middle rows are convex blend of the first/last rows. */
SrfPoints = Srf -> Points;
for (i = IsNotRational; i <= MaxCoord; i++) /* First row. */
CAGD_GEN_COPY(SrfPoints[i], Crv1Points[i],
sizeof(CagdRType) * Len);
/* Make a copy of the last row. */
for (i = IsNotRational; i <= MaxCoord; i++) /* Last row. */
CAGD_GEN_COPY(&SrfPoints[i][Len * (OtherLen - 1)], Crv2Points[i],
sizeof(CagdRType) * Len);
/* And compute the internal rows, if any: */
for (j = 1; j < OtherLen - 1; j++) {
t = ((CagdRType) j) / (OtherLen - 1);
t1 = 1.0 - t;
for (i = IsNotRational; i <= MaxCoord; i++) {
SrfDestPt = &SrfPoints[i][Len * j];
Crv1SrcPt = Crv1Points[i];
Crv2SrcPt = Crv2Points[i];
for (k = 0; k < Len; k++)
SrfDestPt[k] = t1 * Crv1SrcPt[k] + t * Crv2SrcPt[k];
}
}
CagdCrvFree(Crv1);
CagdCrvFree(Crv2);
return Srf;
}
/*****************************************************************************
* DESCRIPTION: M
* Constructs a bilinear surface between the four provided points. M
* *
* PARAMETERS: M
* Pt00, Pt01, Pt10, Pt11: The four points to consturct a bilinear between. M
* *
* RETURN VALUE: M
* CagdSrfStruct *: A bilinear surface with four corners at Ptij. M
* *
* KEYWORDS: M
* CagdBilinearSrf, Bilinear surface, surface constructors M
*****************************************************************************/
CagdSrfStruct *CagdBilinearSrf(CagdPtStruct *Pt00,
CagdPtStruct *Pt01,
CagdPtStruct *Pt10,
CagdPtStruct *Pt11)
{
CagdCrvStruct
*Crv1 = CagdMergePtPt(Pt00, Pt01),
*Crv2 = CagdMergePtPt(Pt10, Pt11);
CagdSrfStruct
*Srf = CagdRuledSrf(Crv1, Crv2, 2, 2);
CagdCrvFree(Crv1);
CagdCrvFree(Crv2);
return Srf;
}
/*****************************************************************************
* DESCRIPTION: M
* Promotes a curve to a surface by creating a ruled surface between the M
* curve to itself. Dir controls if the curve should be U or V surface M
* direction. M
* The resulting surface is degenerate in that its speed is zero in the M
* ruled direction and hence thesurface is not regular. M
* *
* PARAMETERS: M
* Crv: A Crv to promote into a surface M
* Dir: Direction of ruling. Either U or V. M
* *
* RETURN VALUE: M
* CagdSrfStruct *: The surface promoted from Crv. M
* *
* KEYWORDS: M
* CagdPromoteCrvToSrf M
*****************************************************************************/
CagdSrfStruct *CagdPromoteCrvToSrf(CagdCrvStruct *Crv, CagdSrfDirType Dir)
{
CagdSrfStruct *TSrf,
*Srf = CagdRuledSrf(Crv, Crv, 2, 2);
switch (Dir) {
case CAGD_CONST_U_DIR:
break;
case CAGD_CONST_V_DIR:
TSrf = CagdSrfReverse2(Srf);
CagdSrfFree(Srf);
Srf = TSrf;
break;
default:
CAGD_FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
break;
}
return Srf;
}